#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
// 仅供初级教学使用
const int BACKLOG = 8;

class TcpServer
{
public:
    TcpServer() : _sockfd(-1), _port(8080), _ip("0.0.0.0")
    {
        memset(&_addr, 0, sizeof(_addr));
        // signal(SIGPIPE, SIG_IGN);
        _addr.sin_family = AF_INET;                // 使用 IPv4
        _addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网络接口
        _addr.sin_port = htons(_port);             // 设置端口号（网络字节序）
    }
    // TcpServer() : _sockfd(-1), _port(8080), _ip("0.0.0.0")
    // {
    //     std::cerr << "[Constructor] Entering..." << std::flush; // 调试信息 1
    //     memset(&_addr, 0, sizeof(_addr));
    //     std::cerr << "[Constructor] After memset." << std::flush; // 调试信息 2
    //     // signal(SIGPIPE, SIG_IGN); // 保持注释
    //     _addr.sin_family = AF_INET;
    //     std::cerr << "[Constructor] After setting family." << std::flush; // 调试信息 3
    //     _addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //     std::cerr << "[Constructor] After setting addr." << std::flush; // 调试信息 4
    //     _addr.sin_port = htons(_port);
    //     std::cerr << "[Constructor] After setting port." << std::flush; // 调试信息 5
    //     std::cerr << "[Constructor] Exiting..." << std::flush; // 调试信息 6
    // }
    ~TcpServer()
    {}

    bool start()
    {
        // 创建socket
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(_sockfd < 0)
        {
            std::cerr << "创建失败~" << std::endl;
            return false;
        }
        
        // 绑定socket
        if(bind(_sockfd, (struct sockaddr*)&_addr, sizeof(_addr)) < 0)
        {
            std::cerr << "绑定失败~" << std::endl;
            return false;
        }

        // 监听
        if(listen(_sockfd, BACKLOG) < 0)
        {
            std::cerr << "监听失败~" << std::endl;
            return false;
        }

        return true;
    }

    // 接受连接
    int acceptclient()
    {
        struct sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);
        int clientfd = accept(_sockfd,(struct sockaddr*)&client_addr, &len);
        if(clientfd < 0)
        {
            std::cerr << "客户端连接失败~" << std::endl;
            return -1;
        }
        std::cout << "客户端连接成功~" << std::endl;
        return clientfd;
    }

    // 接收数据
    bool recvMsg(int clientfd,std::string &buf)
    {
        char buf_tmp[1024] = {0};
        ssize_t s = read(clientfd, buf_tmp, sizeof(buf_tmp));
        if(s > 0)
        {
            buf.assign(buf_tmp, s);
            return true;
        }
        else if(s == 0)
        {
            std::cout << "客户端关闭连接~" << std::endl;
            return false;
        }
        else
        {
            std::cerr << "接收数据失败~" << std::endl;
            return false;
        }
    }

    // 发送数据
    bool sendMsg(int clientfd,const std::string &buf)
    {
        ssize_t w = write(clientfd, buf.c_str(), buf.size());
        if(w > 0)
        {
            return true;
        }
        else if(w == 0)
        {
            std::cout << "客户端关闭连接~" << std::endl;
            return false;
        }
        else
        {
            std::cerr << "发送数据失败~" << std::endl;
        }
        return false;
    }

    // 关闭连接
    void closeclient(int clientfd)
    {
        close(clientfd);
        clientfd = -1;
    }

    // 关闭监听
    void stop()
    {
        close(_sockfd);
        _sockfd = -1;
    }

private:
    int _sockfd;
    int _port;
    struct sockaddr_in _addr;
    std::string _ip;
};